package gases.as3.librarys.core.net.cpp.struct
{
	import flash.utils.Dictionary;

	public class Struct extends Object
	{
		public function Struct()
		{
			_elements = new Array();
			_elementDict = new Dictionary(true);
		}
		
		public function get bytesLength():int
		{
			return _bytesLength;
		}
		
		/**
		 * 填充数据,类型,长度,值, 会按照此填充的顺序解析,所以顺序一定不能错 
		 * encode的时候,数据值需要填写, decode的时候数据值可以不填
		 * @param name 数据名
		 * @param type 数据类型
		 * @param length 数据长度
 		 * @param value 数据的值
		 * 
		 */
		public function add(name:String, type:String, length:int = 0, value:* = null):void
		{
			var leng:int = 0;
			if(value is Struct)
				leng = Struct(value).bytesLength;
			else
				leng = length;
			
			var element:StructElement = new StructElement(name,type,value,leng);
			_elements.push(element);
			_elementDict[name] = element;
			_bytesLength += leng;
		}
		
		/**
		 * 返回在_elements相应位置上的StructElement
		 * @param num
		 * @return 
		 * 
		 */		
		public function getElement(num:int):StructElement
		{
			if(_elements[num])
				return _elements[num];
			else
				return null;
		}
		
		/**
		 * 
		 * @return 返回_elements的长度
		 * 
		 */		
		public function get length():int
		{
			return _elements.length;
		}
		
		public function getValue(name:String):*
		{
			var element:StructElement = _elementDict[name] as StructElement;
			if(element && element.value)
				return element.value;
			return null;
		}
		
		/**
		 * 设置值
		 * @param name 对应的KEY
		 * @param value 对应的值 
		 * @return 是否设置成功
		 * 
		 */		
		public function setValue(name:String,value:*):Boolean
		{
			var element:StructElement = _elementDict[name] as StructElement;
			if(element && (name == element.name))
			{
				element.value = value;
				return true;
			}
			else
				return false;
		}
		
		/**
		 * 释放内存，并且把bytesLenth,elements,elementsDict都还原
		 * 
		 */		
		public function clear():void
		{
			dispose();
			_bytesLength = 0;
			_elements = new Array();
			_elementDict = new Dictionary(true);
		}
		
		/**
		 * 注销所有的StructElement的value值 
		 * 
		 */		
		public function resetAllValue():void
		{
			var len:int = _elements.length;
			for(var i:int = 0;i < len;i++)
			{
				var element:StructElement = _elements[i];
				if(element)
					element.value = null;
			}
		}
		
		/**
		 * 处理，从而释放内存 
		 * 
		 */		
		public function dispose():void
		{
			while(_elements.length > 0)
				StructElement(_elements.shift()).dispose();
			_elements = null;
			
			for each(var ele:StructElement in _elementDict)
			{
				_elementDict[ele.name] = null;
				delete _elementDict[ele.name];
			}
			_elementDict = null;
			_bytesLength = 0;
		}
		
		/**
		 * 字节长度 
		 */		
		private var _bytesLength:int = 0;
		
		/**
		 *存放structElement的数组 
		 */		
		private var _elements:Array;
		
		/**
		 * stuctElement对应的字典，根据name为标示 
		 */		
		private var _elementDict:Dictionary;
	}
}